/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sane;

import java.io.StringWriter;
import java.util.ArrayList;
import uk.ac.bath.base.MachineIF;
import uk.ac.bath.base.Value;

/**
 *
 * @author pjl
 */
public final class Network implements MachineIF, Cloneable {

    final Value x[];
    final Neuron neurons[];
    final int nIn;
    final int nHidden;
    final int nOut;
    private boolean debug = false;

  

    Network(int nIn, int nHidden, int nOut) {

        this.nIn = nIn;
        this.nHidden = nHidden;
        this.nOut = nOut;

        // state vector
        x = new Value[nIn + nHidden + nOut];
        for (int i = 0; i < nIn + nHidden + nOut; i++) {
            x[i] = new Value(0.0);
        }
     
        neurons = new Neuron[nHidden + nOut];
    }

    /**
     * Create hidden neuron
     * @param ptr
     * @param wght
     * @param id
     */
    void addHidden(ArrayList<Integer> ptr, ArrayList<Float> wght, int iHid) {
        int n = ptr.size();

        Value inPack[] = new Value[n];
        Float w[] = new Float[n];
        for (int i = 0; i < n; i++) {
            inPack[i] = x[ptr.get(i)];
            w[i] = wght.get(i);

        }
        neurons[iHid] = new Neuron(inPack, w, x[nIn + iHid]);
    }

    /**
     *  create output neuron
     *
     * @param ptr    ptr into hidden layer
     * @param wgt    weight vector
     * @param iOut   output number
     */
    void addOut(ArrayList<Integer> ptr, ArrayList<Float> wgt, int iOut) {
        int n = ptr.size();
        assert (n == wgt.size());
        Value inPack[] = new Value[n];
        Float w[] = new Float[n];

        for (int i = 0; i < n; i++) {
            inPack[i] = x[ptr.get(i) + nIn];
            w[i] = wgt.get(i);
            assert (w[i] != null);

        }

        neurons[nHidden + iOut] = new Neuron(inPack, w, x[nIn + nHidden + iOut]);

    }

    public boolean isOn(int i) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public float out(int i) {
        return (float) x[nIn + nHidden + i].val;
    }

    public void setIn(int i, float fVal) {
        x[i].val = fVal;
    }

    public int size() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void tick() {
//
//        if (Context.debugNet) {
//            for (int i = 0; i < nIn; i++) {
//                System.out.print(String.format(" %6.4f ", x[i].val));
//            }
//            System.out.print(" # ");
//        }
        for (final Neuron n : neurons) {
            n.fire();
//            if (Context.debugNet) {
//                System.out.print(String.format(" %6.4f ", n.o.val));
//            }
        }
//        if (Context.debugNet) {
//            System.out.println();
//        }
    }

    public void toString(StringWriter w) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException();
    }

    public int sizeIn() {
        return nIn;
    }

    public int sizeOut() {
        return nOut;
    }
}
